package model;

import java.util.Observable;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
/**
 * IODevices class for the simulator.
 * @author DoubleS
 * @version 1.0
 */
public class IODevice extends Observable implements Runnable 
{
  /**
   * Is this thread done yet?
   */
  private boolean my_is_done;
  
  /**
   * The id of this device.
   */
  private final int my_id;
  
  /**
   * Random generator.
   */
  private final Random my_rand;
  
  /**
   * 
   * @param the_id The IO device's ID.
   */
  public IODevice(final int the_id)
  {
    super();
    my_id = the_id;
    my_is_done = false;
    my_rand = new Random();
  }
  
  /**
   * Set whether this thread is done or not.
   * @param the_boolean The boolean.
   */
  public void setIsDone(final boolean the_boolean)
  {
    my_is_done = the_boolean;
  }
  
  /**
   * 
   * @return The id of this device.
   */
  public int getID()
  {
    return my_id;
  }
  
  /**
   * Receive a request from a process. Set a reminder after a random amount of time from
   * 20ms to 49ms.
   * Notify the CPU when it reaches 0.
   */
  public void receiveRequest()
  {
    final int time = my_rand.nextInt(30) + 20;
    final Timer a_timer = new Timer();
    a_timer.schedule(new RemindTask(a_timer), time);
  }
  
  @Override
  public void run()
  {
    while (!my_is_done)
    {
      // do nothing except waiting for a request from a process.
    }
  }

  /**
   * RemindTast is the task triggered by timer.
   * 
   */
  class RemindTask extends TimerTask
  {
    Timer t;
    RemindTask(Timer new_t) {
      this.t = new_t;
    }
    /**
     * This run() is to the task to run after certain time.
     */
    public void run()
    {
      //System.out.println("Time's up!");
      setChanged();
      notifyObservers();
      //System.out.println("IO interrupt!");
      t.cancel(); //Not necessary because we call System.exit
    }
  }
}
